using System.Linq.Expressions;
using Shard.Contracts;
using SqlSugar;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Linq;

namespace Shared.SqlSugarCore.Repository;

/// <summary>
/// SqlSugar仓储实现
/// </summary>
public  class SqlSugarRepository<TEntity, TKey> : ISqlSugarRepository<TEntity, TKey>, ITransientDependency
    where TEntity : class, IEntity<TKey>,new()
{
    protected ISqlSugarClient DbClient { get; }

    public SqlSugarRepository(ISqlSugarClient sqlSugarClient)
    {
        DbClient = sqlSugarClient;
    }

    /// <summary>
    /// 是否启用变更跟踪
    /// </summary>
    public bool? IsChangeTrackingEnabled => false;

    /// <summary>
    /// 异步查询执行器(ABP框架接口，SqlSugar未使用)
    /// </summary>
    public IAsyncQueryableExecuter AsyncExecuter => null;

    /// <summary>
    /// 获取SQL语句
    /// </summary>
    /// <param name="selectExpression">查询表达式</param>
    /// <returns>SQL语句</returns>
    public string ToSql<TResult>(Expression<Func<TEntity, TResult>> selectExpression)
    {
        return DbClient.Queryable<TEntity>().Select(selectExpression).ToSqlString();
    }

    /// <summary>
    /// 查找符合条件的第一条记录
    /// </summary>
    /// <param name="predicate">查询条件</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>实体对象</returns>
    public async Task<TEntity> FirstAsync(Expression<Func<TEntity, bool>> predicate,
        CancellationToken cancellationToken = default)
    {
        return await DbClient.Queryable<TEntity>().FirstAsync(predicate, cancellationToken);
    }

    /// <summary>
    /// 查找符合条件的第一条记录，如果不存在返回默认值
    /// </summary>
    /// <param name="predicate">查询条件</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>实体对象或默认值</returns>
    public async Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate,
        CancellationToken cancellationToken = default)
    {
        return await DbClient.Queryable<TEntity>().FirstAsync(predicate, cancellationToken);
    }

    /// <summary>
    /// 判断是否存在符合条件的记录
    /// </summary>
    /// <param name="predicate">查询条件</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>是否存在</returns>
    public async Task<bool> AnyAsync(Expression<Func<TEntity, bool>> predicate,
        CancellationToken cancellationToken = default)
    {
        return await DbClient.Queryable<TEntity>().AnyAsync(predicate, cancellationToken);
    }

    /// <summary>
    /// 获取分页数据
    /// </summary>
    /// <param name="skipCount">跳过数量</param>
    /// <param name="maxResultCount">最大返回数量</param>
    /// <param name="predicate">查询条件</param>
    /// <param name="sorting">排序表达式</param>
    /// <param name="isAsc">是否升序</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>分页结果</returns>
    public async Task<(List<TEntity> Items, long TotalCount)> GetPagedListAsync(
        int skipCount,
        int maxResultCount,
        Expression<Func<TEntity, bool>> predicate = null,
        Expression<Func<TEntity, object>> sorting = null,
        bool isAsc = true,
        CancellationToken cancellationToken = default)
    {
        var query = DbClient.Queryable<TEntity>();

        if (predicate != null)
        {
            query = query.Where(predicate);
        }

        if (sorting != null)
        {
            query = isAsc ? query.OrderBy(sorting) : query.OrderByDescending(sorting);
        }

        var totalCount = await query.CountAsync(cancellationToken);
        var items = await query.Skip(skipCount).Take(maxResultCount).ToListAsync(cancellationToken);

        return (items, totalCount);
    }

    /// <summary>
    /// 批量删除
    /// </summary>
    /// <param name="predicate">删除条件</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>影响行数</returns>
    public virtual async Task<int> DeleteAsync(Expression<Func<TEntity, bool>> predicate,
        CancellationToken cancellationToken = default)
    {
        return await DbClient.Deleteable<TEntity>().Where(predicate).ExecuteCommandAsync(cancellationToken);
    }

    /// <summary>
    /// 批量更新
    /// </summary>
    /// <param name="predicate">更新条件</param>
    /// <param name="updateExpression">更新表达式</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>影响行数</returns>
    public async Task<int> UpdateAsync(Expression<Func<TEntity, bool>> predicate,
        Expression<Func<TEntity, TEntity>> updateExpression, CancellationToken cancellationToken = default)
    {
        return await DbClient.Updateable<TEntity>().SetColumns(updateExpression).Where(predicate)
            .ExecuteCommandAsync(cancellationToken);
    }

    /// <summary>
    /// 批量插入
    /// </summary>
    /// <param name="entities">实体集合</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>影响行数</returns>
    public async Task<int> InsertManyAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default)
    {
        return await DbClient.Insertable(entities.ToList()).ExecuteCommandAsync(cancellationToken);
    }

    #region ABP仓储接口实现

    /// <summary>
    /// 获取实体列表
    /// </summary>
    public virtual async Task<List<TEntity>> GetListAsync(bool includeDetails = false,
        CancellationToken cancellationToken = default)
    {
        return await DbClient.Queryable<TEntity>().ToListAsync(cancellationToken);
    }

    /// <summary>
    /// 获取记录总数
    /// </summary>
    public virtual async Task<long> GetCountAsync(CancellationToken cancellationToken = default)
    {
        return await DbClient.Queryable<TEntity>().CountAsync(cancellationToken);
    }

    /// <summary>
    /// 获取分页列表（ABP方式）
    /// </summary>
    public virtual async Task<List<TEntity>> GetPagedListAsync(int skipCount, int maxResultCount, string sorting,
        bool includeDetails = false, CancellationToken cancellationToken = default)
    {
        var query = DbClient.Queryable<TEntity>();

        if (!string.IsNullOrWhiteSpace(sorting)) 
        {
            // 简单处理排序字符串，格式: "Name asc, Age desc"
            var sortItems = sorting.Split(',');
            foreach (var sortItem in sortItems)
            {
                var parts = sortItem.Trim().Split(' ');
                if (parts.Length > 1)
                {
                    var propertyName = parts[0].Trim();
                    var isAsc = parts[1].Trim().ToLower() != "desc";
            
                    // 动态创建表达式
                    var parameter = Expression.Parameter(typeof(TEntity), "x");
                    var property = Expression.Property(parameter, propertyName);
                    var conversion = Expression.Convert(property, typeof(object));
                    var lambda = Expression.Lambda<Func<TEntity, object>>(conversion, parameter);
            
                    query = isAsc
                        ? query.OrderBy(lambda)
                        : query.OrderByDescending(lambda);
                }
                else
                {
                    // 默认升序
                    var propertyName = parts[0].Trim();
                    var parameter = Expression.Parameter(typeof(TEntity), "x");
                    var property = Expression.Property(parameter, propertyName);
                    var conversion = Expression.Convert(property, typeof(object));
                    var lambda = Expression.Lambda<Func<TEntity, object>>(conversion, parameter);
            
                    query = query.OrderBy(lambda);
                }
            }
        }

        return await query.Skip(skipCount).Take(maxResultCount).ToListAsync(cancellationToken);
    }

    /// <summary>
    /// 获取查询对象（不支持，SqlSugar使用不同的查询方式）
    /// </summary>
    public virtual IQueryable<TEntity> WithDetails()
    {
        throw new NotSupportedException("SqlSugar不支持IQueryable方式的导航属性加载");
    }

    /// <summary>
    /// 获取查询对象（不支持，SqlSugar使用不同的查询方式）
    /// </summary>
    public virtual IQueryable<TEntity> WithDetails(params Expression<Func<TEntity, object>>[] propertySelectors)
    {
        throw new NotSupportedException("SqlSugar不支持IQueryable方式的导航属性加载");
    }

    /// <summary>
    /// 获取查询对象（不支持，SqlSugar使用不同的查询方式）
    /// </summary>
    public virtual Task<IQueryable<TEntity>> WithDetailsAsync()
    {
        throw new NotSupportedException("SqlSugar不支持IQueryable方式的导航属性加载");
    }

    /// <summary>
    /// 获取查询对象（不支持，SqlSugar使用不同的查询方式）
    /// </summary>
    public virtual Task<IQueryable<TEntity>> WithDetailsAsync(
        params Expression<Func<TEntity, object>>[] propertySelectors)
    {
        throw new NotSupportedException("SqlSugar不支持IQueryable方式的导航属性加载");
    }

    /// <summary>
    /// 获取查询对象（不支持，SqlSugar使用不同的查询方式）
    /// </summary>
    public virtual Task<IQueryable<TEntity>> GetQueryableAsync()
    {
        throw new NotSupportedException("SqlSugar不支持IQueryable方式的查询");
    }

    /// <summary>
    /// 根据条件获取实体列表
    /// </summary>
    public virtual async Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate,
        bool includeDetails = false, CancellationToken cancellationToken = default)
    {
        return await DbClient.Queryable<TEntity>().Where(predicate).ToListAsync(cancellationToken);
    }

    /// <summary>
    /// 插入实体
    /// </summary>
    public virtual async Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false,
        CancellationToken cancellationToken = default)
    {
        await DbClient.Insertable(entity).ExecuteCommandAsync(cancellationToken);
        return entity;
    }

    /// <summary>
    /// 批量插入实体（不返回影响行数）
    /// </summary>
    public virtual async Task InsertManyAsync(IEnumerable<TEntity> entities, bool autoSave = false,
        CancellationToken cancellationToken = default)
    {
        await DbClient.Insertable(entities.ToList()).ExecuteCommandAsync(cancellationToken);
    }

    /// <summary>
    /// 更新实体
    /// </summary>
    public virtual async Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false,
        CancellationToken cancellationToken = default)
    {
        await DbClient.Updateable(entity).ExecuteCommandAsync(cancellationToken);
        return entity;
    }

    /// <summary>
    /// 批量更新实体
    /// </summary>
    public virtual async Task UpdateManyAsync(IEnumerable<TEntity> entities, bool autoSave = false,
        CancellationToken cancellationToken = default)
    {
        await DbClient.Updateable(entities.ToList()).ExecuteCommandAsync(cancellationToken);
    }

    /// <summary>
    /// 删除实体
    /// </summary>
    public virtual async Task DeleteAsync(TEntity entity, bool autoSave = false,
        CancellationToken cancellationToken = default)
    {
        await DbClient.Deleteable(entity).ExecuteCommandAsync(cancellationToken);
    }

    /// <summary>
    /// 批量删除实体
    /// </summary>
    public virtual async Task DeleteManyAsync(IEnumerable<TEntity> entities, bool autoSave = false,
        CancellationToken cancellationToken = default)
    {
        await DbClient.Deleteable<TEntity>(entities.ToList()).ExecuteCommandAsync(cancellationToken);
    }

    /// <summary>
    /// 查找符合条件的实体
    /// </summary>
    public virtual async Task<TEntity?> FindAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = true,
        CancellationToken cancellationToken = default)
    {
        return await DbClient.Queryable<TEntity>().FirstAsync(predicate, cancellationToken);
    }

    /// <summary>
    /// 获取符合条件的实体，如不存在则抛出异常
    /// </summary>
    public virtual async Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = true,
        CancellationToken cancellationToken = default)
    {
        var entity = await DbClient.Queryable<TEntity>().FirstAsync(predicate, cancellationToken);
        if (entity == null)
        {
            throw new EntityNotFoundException(typeof(TEntity));
        }

        return entity;
    }

    /// <summary>
    /// 根据条件删除实体
    /// </summary>
    public virtual async Task DeleteAsync(Expression<Func<TEntity, bool>> predicate, bool autoSave = false,
        CancellationToken cancellationToken = default)
    {
        await DbClient.Deleteable<TEntity>().Where(predicate).ExecuteCommandAsync(cancellationToken);
    }

    /// <summary>
    /// 直接删除实体（等同于DeleteAsync(predicate)）
    /// </summary>
    public virtual async Task DeleteDirectAsync(Expression<Func<TEntity, bool>> predicate,
        CancellationToken cancellationToken = default)
    {
        await DbClient.Deleteable<TEntity>().Where(predicate).ExecuteCommandAsync(cancellationToken);
    }

    /// <summary>
    /// 根据ID获取实体
    /// </summary>
    public virtual async Task<TEntity> GetAsync(TKey id, bool includeDetails = true,
        CancellationToken cancellationToken = default)
    {
        var entity = await DbClient.Queryable<TEntity>().InSingleAsync(id);
        if (entity == null)
        {
            throw new EntityNotFoundException(typeof(TEntity), id);
        }

        return entity;
    }

    /// <summary>
    /// 根据ID查找实体
    /// </summary>
    public virtual async Task<TEntity?> FindAsync(TKey id, bool includeDetails = true,
        CancellationToken cancellationToken = default)
    {
        return await DbClient.Queryable<TEntity>().InSingleAsync(id);
    }

    /// <summary>
    /// 根据ID删除实体
    /// </summary>
    public virtual async Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
    {
        await DbClient.Deleteable<TEntity>().In(id).ExecuteCommandAsync(cancellationToken);
    }

    /// <summary>
    /// 根据多个ID批量删除实体
    /// </summary>
    public virtual async Task DeleteManyAsync(IEnumerable<TKey> ids, bool autoSave = false,
        CancellationToken cancellationToken = default)
    {
        await DbClient.Deleteable<TEntity>().In(ids.ToList()).ExecuteCommandAsync(cancellationToken);
    }

    #endregion
}

/// <summary>
/// SqlSugar仓储实现（针对Guid主键）
/// </summary>
public class SqlSugarRepository<TEntity> : SqlSugarRepository<TEntity, Guid>, ISqlSugarRepository<TEntity>
    where TEntity : class, IEntity<Guid>, new()
{
    public SqlSugarRepository(ISqlSugarClient sqlSugarClient)
        : base(sqlSugarClient)
    {
    }
}